package com.hwadee.property.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class DateUtil {
    // 默认日期格式
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    // 使用 ThreadLocal 来存储 SimpleDateFormat，确保线程安全
    private static final ThreadLocal<SimpleDateFormat> sdfThreadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat(DEFAULT_DATE_FORMAT));

    // 如果需要支持多种日期格式，可以使用一个线程安全的 Map 来存储
    private static final ConcurrentMap<String, ThreadLocal<SimpleDateFormat>> formatMap = new ConcurrentHashMap<>();

    /**
     * 将日期对象转换为字符串
     *
     * @param date       日期对象
     * @param dateFormat 日期格式（可选，默认为 yyyy-MM-dd）
     * @return 转换后的字符串
     */
    public static String dateToString(Date date, String dateFormat) {
        if (date == null) {
            throw new IllegalArgumentException("Date cannot be null");
        }
        if (dateFormat == null || dateFormat.isEmpty()) {
            dateFormat = DEFAULT_DATE_FORMAT;
        }
        ThreadLocal<SimpleDateFormat> sdfThreadLocal = getFormatThreadLocal(dateFormat);
        return sdfThreadLocal.get().format(date);
    }

    /**
     * 将日期对象转换为字符串（使用默认格式）
     *
     * @param date 日期对象
     * @return 转换后的字符串
     */
    public static String dateToString(Date date) {
        return dateToString(date, DEFAULT_DATE_FORMAT);
    }

    /**
     * 将字符串转换为日期对象
     *
     * @param dateString 字符串日期
     * @param dateFormat 日期格式（可选，默认为 yyyy-MM-dd）
     * @return 转换后的日期对象
     * @throws ParseException 如果字符串格式不正确
     */
    public static Date stringToDate(String dateString, String dateFormat) throws ParseException {
        if (dateString == null || dateString.isEmpty()) {
            throw new IllegalArgumentException("Date string cannot be null or empty");
        }
        if (dateFormat == null || dateFormat.isEmpty()) {
            dateFormat = DEFAULT_DATE_FORMAT;
        }
        ThreadLocal<SimpleDateFormat> sdfThreadLocal = getFormatThreadLocal(dateFormat);
        try {
            sdfThreadLocal.get().setLenient(false); // 严格解析日期
            return sdfThreadLocal.get().parse(dateString);
        } catch (ParseException e) {
            throw new BusinessException(ErrorCodes.INVALID_INPUT, "日期格式不正确，请使用格式：yyyy-MM-dd HH:mm:ss");
        }
    }

    /**
     * 将字符串转换为日期对象（使用默认格式）
     *
     * @param dateString 字符串日期
     * @return 转换后的日期对象
     * @throws ParseException 如果字符串格式不正确
     */
    public static Date stringToDate(String dateString) throws ParseException {
        if (dateString != null) return stringToDate(dateString, DEFAULT_DATE_FORMAT);
        else return null;
    }

    /**
     * 获取 ThreadLocal 中的 SimpleDateFormat，如果不存在则创建
     *
     * @param dateFormat 日期格式
     * @return ThreadLocal<SimpleDateFormat>
     */
    private static ThreadLocal<SimpleDateFormat> getFormatThreadLocal(String dateFormat) {
        return formatMap.computeIfAbsent(dateFormat, k -> ThreadLocal.withInitial(() -> new SimpleDateFormat(dateFormat)));
    }
}
